#pragma once

// typedef std::function<void()> fun_t;

template <class T>
using fun_t = std::function<void(T)>;


// using fun_t = std::function<void(ThreadData*)>;

template <class T>
class Thread
{

public:
    Thread(const std::string threadname, fun_t<T> fun, T data)
        : _tid(0), _threadname(threadname), _isruning(false), _fun(fun), _data(data)
    {
    }

    static void *ThreadRoutine(void *args)
    {
        Thread *td = static_cast<Thread *>(args);

        td->_fun(td->_data); 

        return nullptr;
    }
    void Start()
    {
        if (_isruning)
            return;
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this /*这里将this传递过去方便调用用户级方法*/);
        if (n)
            Start(); // 如果创建失败就重新创建
        else
            _isruning = true;
    }

    void Join()
    {
        if (!_isruning)
            return;
        int n = pthread_join(_tid, nullptr);
        if (n)
            return;
        _isruning = false;
    }

    std::string ThreadName()
    {
        return _threadname;
    }

    bool IsRuning()
    {
        return _isruning;
    }

private:
    pthread_t _tid;
    std::string _threadname;
    bool _isruning;
    fun_t<T> _fun;
    T _data;
};